<?php

namespace app\socket\types;

use app\socket\object\Game;
use think\helper\Str;

/**
 * 扫雷房间
 * @property string $roomId 房间号
 * @property int $state 0:等待玩家进入 1:游戏进行中 2:游戏结束
 * @property array $fds 房间中的Fd集合
 * @property int $round 游戏回合 0
 * @property int $count 游戏局数
 * @property int $fd 当前回合执行的玩家
 * @property array $map 地图
 * @property int $mapType 地图类型
 * @property array $open 地图已开放的情况
 */
class SwRoom extends Game
{
    public $pk = "roomId";
    public $cacheKey = ["swoole", "room"];

    public $type = [
        'fds' => "array",
        'map' => "array",
        'open' => 'array'
    ];

    /**
     * 获取一个不存在房间号创建房间
     *
     *  SISMEMBER room:list 房间号 判断当前房间号是否已存在
     *  SADD room:list 房间号 向房间列表中加入一个房间号
     * @return string
     */
    public static function getNotExistRoom()
    {
        $obj = new FcRoom();
        $key = implode(":", ["swoole", "room", "list"]);
        while (true) {
            $roomId = "r" . Str::random(6, 1);
            if (!$obj->redis->SISMEMBER($key, $roomId)) {
                $obj->redis->sadd($key, $roomId);
                return $roomId;
            }
        }
    }

    /**
     * 房间中添加一个玩家
     *
     * @param SwPlayer $player
     * @return $this
     */
    public function add($player)
    {
        $fds = $this->fds ?: [];


        if (!in_array($player->fd, $fds)) {
            $player->sort = count($fds) + 1;
            array_push($fds, $player->fd);
            $this->fds = $fds;
        }

        return $this;
    }

    /**
     * 房间中删除一个玩家
     *
     * @param SwPlayer $player
     * @return void
     */
    public function remove($player)
    {
        $fds = $this->fds ?: [];
        $index = array_search($player->fd, $fds);
        if ($index !== false) {
            array_splice($fds, $index, 1);
        }
        $this->fds  = $fds;
        if (!count($fds)) {
            $this->delete();
            $this->redis->SREM(implode(":", ["swoole", "room", "list"]), $this->roomId);
        }
        $this->save();
        return $this;
    }

    /**
     * 获取下一个要执行回合的人的fd
     *
     * @param int $fd 当前回合人的fd
     * @return void
     */
    public function next($fd)
    {
        $fds = $this->fds ?: [];
        $index = array_search($fd, $fds);

        if ($index !== false) {
            $next = $index + 1;
            if ($next >= count($fds)) {
                $next = 0;
            }
            return intval($fds[$next]);
        }

        return false;
    }

    /**
     * 记得当前点击的情况 解析出已开放的格子
     *
     * @param array $info
     * @return void
     */
    public function log($info)
    {
        $open = $this->open ?: [];
        $open[$info['index']] = $info['current'];
        $open += $info['close'];
        foreach ($info['open'] as $index) {
            $open[$index] = 0;
        }
        $this->open = $open;
    }

    /**
     * 获取房间内其他人的信息
     *
     * @param 当前的玩家 $fd
     * @return array
     */
    public function getOtherPlayers($current)
    {
        $fds = $this->fds ?: [];
        $players = [];
        foreach ($fds as $fd) {
            if ($fd != $current) {
                $players[] = SwPlayer::find($fd);
            }
        }
        return $players;
    }
}
